package com.abigdreamer.swing.component;

import java.awt.Color;
import java.awt.Image;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import com.abigdreamer.swing.app.skin.SkinConst;
import com.abigdreamer.util.SwingResourceManager;

public class JCTextPane extends JTextPane {

	private static final long serialVersionUID = 1L;

	/**
	 * 图片描述
	 */
	public static class ChatPic extends ImageIcon {

		private static final long serialVersionUID = 1L;
		int im;// 图片代号

		public int getIm() {
			return im;
		}

		public void setIm(int im) {
			this.im = im;
		}

		public ChatPic(Image img, int im) {
			super(img);
			this.im = im;
		}
		
		public ChatPic(URL img, int im) {
			super(img);
			this.im = im;
		}
		
		public ChatPic(String img, int im) {
			super(img);
			this.im = im;
		}
	}
	
	/**
	 * 字体属性辅助类
	 */
	public static class FontAndText {
		
		public static final int GENERAL = 0; // 常规
		private String text = "", fontName = "宋体"; // 要输入的文本和字体名称

		private int fontSize = 0; // 字号

		private Color fontColor = new Color(225, 225, 225); // 文字颜色

		private SimpleAttributeSet attrSet = null; // 属性集

		/**
		 * 一个空的构造（可当做换行使用）
		 */
		public FontAndText() {
		}
		
		/**
		 * 将收到的消息转化为自定义的字体类对象
		 * @param encodeText
		 */
		public FontAndText(String encodeText) {
			String[] msgs = encodeText.split("[|]");
			String fontName = "";
			int fontSize = 0;
			String[] color;
			String text = encodeText;
			Color fontC = new Color(222, 222, 222);
			
			/* 这里简单处理，表示存在字体信息 */
			if (msgs.length >= 4) {
				fontName = msgs[0];
				fontSize = Integer.parseInt(msgs[1]);
				color = msgs[2].split("[-]");
				if (color.length == 3) {
					int r = Integer.parseInt(color[0]);
					int g = Integer.parseInt(color[1]);
					int b = Integer.parseInt(color[2]);
					fontC = new Color(r, g, b);
				}
				text = "";
				// TODO can replace with the code : text = msgs[3];
				for (int i = 3; i < msgs.length; i++) {
					text = text + msgs[i];
				}
			}
			
			this.text = text;
			this.fontName = fontName;
			this.fontSize = fontSize;
			this.fontColor = fontC;
		}

		public FontAndText(String text, String fontName, int fontSize, Color color) {
			this.text = text;
			this.fontName = fontName;
			this.fontSize = fontSize;
			this.fontColor = color;
		}

		/**
		 * 返回属性集
		 * 
		 * @return
		 */
		public SimpleAttributeSet getAttrSet() {
			attrSet = new SimpleAttributeSet();
			if (fontName != null) {
				StyleConstants.setFontFamily(attrSet, fontName);
			}
			StyleConstants.setBold(attrSet, false);
			StyleConstants.setItalic(attrSet, false);
			StyleConstants.setFontSize(attrSet, fontSize);
			if (fontColor != null)
				StyleConstants.setForeground(attrSet, fontColor);
			return attrSet;
		}

		public String toString() {
			// 将消息分为四块便于在网络上传播
			return fontName + "|" + fontSize + "|" + fontColor.getRed() + "-" + fontColor.getGreen() + "-" + fontColor.getBlue() + "|" + text;
		}

		public String getText() {
			return text;
		}

		public void setText(String text) {
			this.text = text;
		}

		public Color getFontColor() {
			return fontColor;
		}

		public void setFontColor(Color color) {
			this.fontColor = color;
		}

		public String getFontName() {
			return fontName;
		}

		public void setFontName(String name) {
			this.fontName = name;
		}

		public int getFontSize() {
			return fontSize;
		}

		public void setFontSize(int size) {
			this.fontSize = size;
		}
	}
	
	public static class PicInfo {

		int pos;
		String val;

		public PicInfo(int pos, String val) {
			this.pos = pos;
			this.val = val;
		}

		public int getPos() {
			return pos;
		}

		public void setPos(int pos) {
			this.pos = pos;
		}

		public String getVal() {
			return val;
		}

		public void setVal(String val) {
			this.val = val;
		}

	}
	
	public static class TextIconInfo {
		
		private int index;
		private Icon icon;
		
		public TextIconInfo(int index, Icon icon) {
			this.index = index;
			this.icon = icon;
		}

		public int getIndex() {
			return index;
		}

		public void setIndex(int index) {
			this.index = index;
		}

		public Icon getIcon() {
			return icon;
		}

		public void setIcon(Icon icon) {
			this.icon = icon;
		}
	}

	/**
	 * get the icons in the textpane
	 * 
	 * @author Darkness
	 * @date 2012-1-11 下午07:26:25 
	 * @version V1.0  
	 * @return
	 */
	public List<TextIconInfo> getIcons() {
		
		List<TextIconInfo> textIconInfos = new ArrayList<TextIconInfo>();
		
		// 遍历jtextpane找出所有的图片信息封装成指定格式
		for (int i = 0; i < this.getText().length(); i++) {
			if (getStyledDocument().getCharacterElement(i).getName().equals("icon")) {
				Icon cupic = StyleConstants.getIcon(getStyledDocument().getCharacterElement(i).getAttributes());
				textIconInfos.add(new TextIconInfo(i, cupic));
			}
		}
		
		return textIconInfos;
	}
	
	/**
	 * 重组发送的表情信息
	 * 
	 * @return 重组后的信息串 格式为 位置&代号+位置&代号+……
	 */
	public String buildPicInfo() {
		StringBuilder sb = new StringBuilder("");
		
		List<TextIconInfo> icons = getIcons();
		for (TextIconInfo textIconInfo : icons) {
			ChatPic cupic = (ChatPic)textIconInfo.getIcon();
			
			sb.append(textIconInfo.getIndex() + "&" + cupic.getIm() + "+");
		}
		
		return sb.toString();
	}

	public String getPicText() {
		return getText() + "*" + buildPicInfo();
	}

	private void insert(FontAndText attrib) {
		try {
			getStyledDocument().insertString(getStyledDocument().getLength(), attrib.getText() + "\n", attrib.getAttrSet());
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
		setCaretPosition(getStyledDocument().getLength()); // 设置滚动到最下边
	}

	private void insert(int start, List<PicInfo> receivdPicInfo) {
		if (receivdPicInfo.size() <= 0) {
			return;
		} else {
			for (int i = 0; i < receivdPicInfo.size(); i++) {
				PicInfo pic = receivdPicInfo.get(i);
				String fileName;
				setCaretPosition(start + pic.getPos()); /* 设置插入位置 */
				fileName = "qqdefaultface/" + pic.getVal() + ".gif";/* 修改图片路径 */
				insertIcon(SwingResourceManager.getIcon( SkinConst.IMAGE_DIR + SkinConst.FILE_SEP + fileName)); /* 插入图片 */

			}
			receivdPicInfo.clear();
		}
		setCaretPosition(getStyledDocument().getLength()); /* 设置滚动到最下边 */
	}

	public void insert(String message) {
		int index = message.lastIndexOf("*");

		/* 很重要的，记录下聊天区域要插入聊天消息的开始位置， */
		if (index > 0 && index < message.length() - 1) {/* 存在表情信息 */
			FontAndText attr = new FontAndText(message.substring(0, index));
			int start = getCaretPosition();
			insert(attr);
			insert(start, receivedPicInfo(message.substring(index + 1, message.length())));
		} else {
			FontAndText attr = new FontAndText(message);
			insert(attr);
		}
	}
	
	/*
	 * 重组收到的表情信息串
	 */
	public List<PicInfo> receivedPicInfo(String picInfos) {

		List<PicInfo> receivdPicInfo = new LinkedList<PicInfo>();

		String[] infos = picInfos.split("[+]");
		for (int i = 0; i < infos.length; i++) {
			String[] tem = infos[i].split("[&]");
			if (tem.length == 2) {
				PicInfo pic = new PicInfo(Integer.parseInt(tem[0]), tem[1]);
				receivdPicInfo.add(pic);
			}
		}

		return receivdPicInfo;
	}
}

